﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using System.Xml;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Controls;

using PlanningGIS.Util.Convertor;
using PlanningGIS.ArcGIS;
using PlanningGIS.Util.Log;
using PlanningGIS.Engine.Controls;

namespace PlanningGIS.DataCheck.model
{
    /// <summary>
    /// 高程点属性异常检查（程点的高程应精确到0.1米，不是此精度的或零值或负值应重点检查，地形高程点（图面不表示）的labx、laby不应赋值，而其他高程点则应该有labx、laby值）
    /// </summary>
    public class TerAttrExceptionCheck : Check
    {
        public int Check(string errType, IFeatureLayer pFeatLyr, IGeometry pGeometry, string whereClause, 
            string fcodename,string elevationname,  string labxname, string labyname)
        {
            IFeatureClass pFeatCls = pFeatLyr.FeatureClass;

            int idxFcode = pFeatCls.FindField(fcodeName);
            if (idxFcode == -1)
            {
               LogHelper.WriteErrLog("[" + pFeatLyr.Name + "图层中未找到分类代码[" + fcodeName + "]字段，检查失败！");
                return -1;
            }

            int idxelevation = pFeatCls.FindField(elevationname);
            if (idxelevation == -1)
            {
               LogHelper.WriteErrLog("[" + pFeatLyr.Name + "图层中未找到高程[" + elevationname + "]字段，检查失败！");
                return -1;
            }

            int idxlabx = pFeatCls.FindField(labxname);
            if (idxlabx == -1)
            {
               LogHelper.WriteErrLog("[" + pFeatLyr.Name + "图层中未找到LABX[" + labxname + "]字段，检查失败！");
                return -1;
            }

            int idxlaby = pFeatCls.FindField(labxname);
            if (idxlaby == -1)
            {
               LogHelper.WriteErrLog("[" + pFeatLyr.Name + "图层中未找到LABY[" + labyname + "]字段，检查失败！");
                return -1;
            }

            if (pFeatCls.ShapeType != esriGeometryType.esriGeometryPoint)
            {
               LogHelper.WriteErrLog("[" + pFeatLyr.Name + "图层不是点状图层，检查失败！");
                return -1;
            }

            ISpatialFilter pSpatialFileter = new SpatialFilterClass();
            pSpatialFileter.Geometry = pGeometry;

            string sql = fcodename + " in ('720101102','720101107','720102102','720200102','720300102')";
            pSpatialFileter.WhereClause = whereClause == "" ? sql : whereClause + " and " + sql;

            pSpatialFileter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
            pSpatialFileter.GeometryField = pFeatCls.ShapeFieldName;

            showFakePro(true);
            LogHelper.WriteLog("正在计算需要检查的要素数目...");

            int max = FeatureClassHelper.GetFeatureCountFromLayer(pFeatLyr, pSpatialFileter);// pFeatCls.FeatureCount(pSpatialFileter);
            

            LogHelper.WriteLog("计算完毕。共有" + max + "个要素参与检查。");
            showFakePro(false);

            if (max == 0)
            {
                LogHelper.WriteLog("没有满足检查要求的要素存在。");
                return -1;
            }

            setProcessBarMax(max);

            IFeatureCursor pFeatCur;
            pFeatCur = pFeatLyr.Search(pSpatialFileter, false);

            IFeature pFeature;

            int count = 0;
            int errCount = 0;

            while ((pFeature = pFeatCur.NextFeature()) != null)
            {
                if (IsStop()) break;

                setProcessBarCurrent(count);
                count++;

                string fcodevlaue = pFeature.get_Value(idxFcode).ToString();

                if (pFeature.get_Value(idxelevation) == DBNull.Value || pFeature.get_Value(idxelevation) == null)
                {
                    RecordListHelper.AddRecordItem(errType, pFeatLyr, null, pFeature, null, pFeature.ShapeCopy, "高程属性为空");
                    errCount++;
                    continue;
                }

                string strelevationvalue=pFeature.get_Value(idxelevation).ToString();
                double elevationvalue = Double.Parse(strelevationvalue);
                if (elevationvalue < 0)
                {
                    RecordListHelper.AddRecordItem(errType, pFeatLyr, null, pFeature, null, pFeature.ShapeCopy, "高程属性为负数");
                    errCount++;
                    continue;
                }

                if (strelevationvalue.Contains(".") && strelevationvalue.IndexOf('.') != strelevationvalue.Length - 2)
                {
                    RecordListHelper.AddRecordItem(errType, pFeatLyr, null, pFeature, null, pFeature.ShapeCopy, "高程属性未精确到0.1");
                    errCount++;
                    continue;
                }

                double labxvalue = Double.Parse(StringHelper.ConvertWRTNull(pFeature.get_Value(idxlabx)));
                double labyvalue = Double.Parse(StringHelper.ConvertWRTNull(pFeature.get_Value(idxlaby)));

                if (fcodevlaue == "720101107")
                {
                    if (labxvalue != 0 || labyvalue != 0)
                    {
                        RecordListHelper.AddRecordItem(errType, pFeatLyr, null, pFeature, null, pFeature.ShapeCopy, "地形高程点LABX、LABY不应赋值");
                        errCount++;
                        continue;
                    }
                }
                else
                {
                    if (labxvalue == 0 || labyvalue == 0)
                    {
                        RecordListHelper.AddRecordItem(errType, pFeatLyr, null, pFeature, null, pFeature.ShapeCopy, "非地形高程点LABX、LABY应赋值");
                        errCount++;
                        continue;
                    }
                }

            }

            finishPro.Invoke();

            DataCheckUtility.ReleaseComObject(pFeature);
            DataCheckUtility.ReleaseComObject(pFeatCur);

            LogHelper.WriteLog("高程点属性异常检查结束。共发现" + errCount + "处错误！\n");

            return errCount;
        }

    }
}
